package com.szzg10.thinking.chapter18;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class StoreCADState {

	public static void main(String[] args) throws IOException {
		List<Class<? extends Shape>> shapeTypes = new ArrayList<Class<? extends Shape>>();
		shapeTypes.add(Circle.class);
		shapeTypes.add(Square.class);
		shapeTypes.add(Line.class);
		
		List<Shape> shapes = new ArrayList<Shape>();
		for(int i = 0; i < 10; i++) {
			shapes.add(Shape.randomFactory());
		}
		for(int i = 0; i < 10; i++) {
			shapes.get(i).setColor(Shape.GREEN);
		}
		
		File file = new File(Worm.FILE_NAME_SERIALIZABLE);
		FileOutputStream fileOutputStream = new FileOutputStream(file);
		ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
		
		objectOutputStream.writeObject(shapeTypes);
		Line.serializeStaticState(objectOutputStream);
		objectOutputStream.writeObject(shapes);
		
		objectOutputStream.close();
		
		for(int i = 0; i < 10; i++) {
			System.out.println(shapes.get(i));
		}
	}
}

abstract class Shape implements Serializable {
	
	public static int RED = 1;
	public static int BLUE = 2;
	public static int GREEN = 3;
	
	private static int count = 0;
	private static Random random = new Random(47);
	
	private int xPos;
	private int yPos;
	private int dimension;
	
	public Shape(int xPos, int yPos, int dimension) {
		this.xPos = xPos;
		this.yPos = yPos;
		this.dimension = dimension;
	}
	
	public abstract int getColor();
	
	public abstract void setColor(int color);
	
	@Override
	public String toString() {
		return getClass() + ": " + ", Color: " + getColor() + ", xPos: " + xPos + ", yPos: " + yPos + ", dimension: " + dimension;
	}
	
	public static Shape randomFactory() {
		int xVal = random.nextInt();
		int yVal = random.nextInt();
		int dim = random.nextInt();
		
		switch(count++ % 3) {
			default:
			case 0: return new Circle(xVal, yVal, dim);
			case 1: return new Square(xVal, yVal, dim);
			case 2: return new Line(xVal, yVal, dim);
		}
	}
}

class Circle extends Shape {

	private static int color = RED;
	
	public Circle(int xPos, int yPos, int dimension) {
		super(xPos, yPos, dimension);
	}
	
	@Override
	public int getColor() {
		return color;
	}

	@Override
	public void setColor(int color) {
		this.color = color;
	}
	
}

class Square extends Shape {

	private static int color;
	
	public Square(int xPos, int yPos, int dimension) {
		super(xPos, yPos, dimension);
		color = RED;
	}
	
	@Override
	public int getColor() {
		return color;
	}

	@Override
	public void setColor(int color) {
		this.color = color;
	}
	
}

class Line extends Shape {

	private static final long serialVersionUID = 1L;
	private static int color;
	
	public Line(int xPos, int yPos, int dimension) {
		super(xPos, yPos, dimension);
	}
	
	public static void serializeStaticState(ObjectOutputStream objectOutputStream) throws IOException {
		objectOutputStream.writeInt(color);
	}
	
	public static void deserializeStaticState(ObjectInputStream objectInputStream) throws IOException {
		color = objectInputStream.readInt();
	}
	
	@Override
	public int getColor() {
		return color;
	}

	@Override
	public void setColor(int color) {
		this.color = color;
	}
	
}

